home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-23 | 8.8 KB | 414 lines | [TEXT/CWIE] |
- /*
- ** MacWT -- a 3d game engine for the Macintosh
- ** © 1995, Bill Hayden and Nikol Software
- ** Free for non-commercial use - address questions to the e-mail address below
- **
- ** Mail: afn28988@freenet.ufl.edu (Bill Hayden)
- ** MacWT FTP site: ftp.circa.ufl.edu/pub/software/ufmug/mirrors/LocalSW/Hayden/
- ** WWW Page: http://grove.ufl.edu:80/~nikolsw
- **
- ** All of the above addresses are due to changes sometime in 1996, so stay tuned
- **
- ** based on wt, by Chris Laurel
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- // Modifications by EDAN SHALEV (edan@netcom.com) 9/26/95
-
- #include <stdlib.h>
- #include <stdio.h>
- #include "wt.h"
- #include "error.h"
- #include "wtmem.h"
- #include "color.h"
- #include "graphfile.h"
- #include "StringUtils.h"
-
-
- static PicHandle PictFromFile(short fref);
- static OSErr CreateCGrafPortFromPict(CGrafPtr *newCGrafPort, PicHandle srcPictH);
- static OSErr SetUpPixMap(PixMapHandle aPixMap, short depth, Rect *bounds, CTabHandle colors, short bytesPerRow);
- static OSErr CreateCGrafPort(CGrafPtr *newCGrafPort, Rect *bounds, short depth, CTabHandle colors, GDHandle useGDevice);
- static OSErr CreateBestCGrafPort(CGrafPtr *tempCGrafPort, Rect *bounds);
-
-
-
- /*****************************************************************************/
-
-
-
- Graphic_file *LoadPICTR(FILE *fp, char *filename)
- {
- Graphic_file *gfile = nil;
- PicHandle hPic;
- RGBColor thePixel;
- long index = 0;
- short h, v;
- GrafPtr savePort;
- short vref, HomeRes, fref;
- OSErr err = noErr;
- CGrafPtr saveCPort;
-
-
-
- HomeRes = CurResFile();
-
- err = GetVol(nil, &vref);
- c2p(filename);
- fref = OpenResFile( (StringPtr)filename );
-
- if (err || fref == -1)
- {
- p2c((StringPtr)filename);
- return gfile;
- }
-
-
- UseResFile( fref );
-
- if (Count1Resources( 'PICT' ))
- {
- hPic = (PicHandle)Get1IndResource( 'PICT', 1 );
- vref = -1;
- }
- else
- {
- err = FSClose( fref );
-
- err = OpenDF( (StringPtr)filename, vref, &fref );
- hPic = PictFromFile(fref);
- err = FSClose (fref);
- }
-
- if (hPic)
- {
- gfile = new_graphic_file();
- gfile->type = gfTrueColor;
- gfile->palette = NULL;
- gfile->width = (*hPic)->picFrame.right - (*hPic)->picFrame.left;
- gfile->height = (*hPic)->picFrame.bottom - (*hPic)->picFrame.top;
- gfile->bitmap = (unsigned char *)wtmalloc(gfile->height * gfile->width * 3);
-
- GetPort(&savePort);
- err = CreateCGrafPortFromPict( &saveCPort, hPic);
- SetPort((GrafPtr)saveCPort);
-
- // I think there is a better (quicker) way to do this, but I'll have to check
-
- for (v = 0; v < (gfile->height); v++)
- for (h = 0; h < (gfile->width); h++)
- {
- GetCPixel(h, v, &thePixel);
- gfile->bitmap[index++] = (unsigned char)(thePixel.red >> 8);
- gfile->bitmap[index++] = (unsigned char)(thePixel.green >> 8);
- gfile->bitmap[index++] = (unsigned char)(thePixel.blue >> 8);
- }
-
- SetPort(savePort);
- CloseCPort(saveCPort);
- DisposePtr((Ptr)saveCPort);
-
-
- if (vref == -1)
- ReleaseResource((Handle)hPic);
- else
- DisposeHandle((Handle)hPic);
- }
-
- UseResFile(HomeRes);
-
- p2c((StringPtr)filename);
-
- return gfile;
- }
-
-
-
-
- static PicHandle PictFromFile(short fref)
- {
- PicHandle thePic;
- const short kPictHeaderSize = 512; // Length of PICT header in bytes
- long pictFileLen; // Length of the PICT file
- OSErr err;
-
-
- err = GetEOF(fref, &pictFileLen);
-
- // Skip over the 512 byte header which we don't need
- err = SetFPos(fref, fsFromStart, kPictHeaderSize);
-
- // Adjust the length of the pict file (shorten by 512) to
- // account for our skipping the first 512 bytes
- pictFileLen -= kPictHeaderSize;
-
- if (pictFileLen <= 0)
- return nil;
-
- // Now, allocate some memory with which to load our pict file in.
- thePic = (PicHandle)NewHandleClear(pictFileLen);
- if (thePic == nil)
- return(nil);
-
- // Lock the buffer
- HLock((Handle)thePic);
-
- // Okay, read in the pict file
- err = FSRead(fref, &pictFileLen, (Ptr)*thePic);
-
- HUnlock((Handle)thePic);
-
- return(thePic);
- }
-
-
-
-
-
- static OSErr CreateCGrafPortFromPict( CGrafPtr *newCGrafPort, PicHandle srcPictH)
- {
- OSErr err;
- GrafPtr savePort;
- CGrafPtr tempCGrafPort;
- Rect pictRect;
-
- *newCGrafPort = NULL;
-
- GetPort(&savePort);
-
- pictRect.left = 0;
- pictRect.top = 0;
- pictRect.right = (**srcPictH).picFrame.right - (**srcPictH).picFrame.left;
- pictRect.bottom = (**srcPictH).picFrame.bottom - (**srcPictH).picFrame.top;
-
- err = CreateBestCGrafPort(&tempCGrafPort, &pictRect);
-
- if (err == noErr)
- {
- SetPort((GrafPtr)tempCGrafPort);
-
- DrawPicture(srcPictH, &pictRect);
-
- *newCGrafPort = tempCGrafPort;
- }
-
- SetPort(savePort);
-
- return err;
- }
-
- static OSErr CreateBestCGrafPort( CGrafPtr *newCGrafPort, Rect *offScreenRect)
- {
- OSErr err = noErr;
- GDHandle baseGDevice;
- PixMapHandle basePixMap;
- Rect tempOffScreenRect;
-
-
- baseGDevice = GetMaxDevice(offScreenRect);
-
- if ((baseGDevice != NULL) && (err == noErr))
- {
- tempOffScreenRect = *offScreenRect;
- OffsetRect(&tempOffScreenRect, -tempOffScreenRect.left, -tempOffScreenRect.top);
- basePixMap = (**baseGDevice).gdPMap;
- err = CreateCGrafPort(newCGrafPort, &tempOffScreenRect, (**basePixMap).pixelSize,
- (**basePixMap).pmTable, baseGDevice);
- }
-
- return err;
- }
-
-
-
- #define kMaxRowBytes 0x3FFE
-
- static OSErr CreateCGrafPort(
- CGrafPtr *newCGrafPort,
- Rect *bounds,
- short depth,
- CTabHandle colors,
- GDHandle useGDevice)
- {
- CGrafPtr tempCGrafPort;
- PixMapHandle newPixMap;
- GDHandle newDevice;
- long qdVersion;
- GrafPtr savedPort;
- SignedByte savedState;
- short bytesPerRow;
- OSErr err;
-
-
- tempCGrafPort = NULL;
- newPixMap = NULL;
- newDevice = NULL;
- err = noErr;
-
-
- if (colors != NULL)
- {
- savedState = HGetState( (Handle)colors );
- HNoPurge( (Handle)colors );
- }
-
- bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) >> 5) << 2;
- err = Gestalt(gestaltQuickdrawVersion, &qdVersion);
-
- if (err == noErr)
- {
-
- if (depth == 1 || depth == 2 || depth == 4 || depth == 8 ||
- ((depth == 16 || depth == 32) && qdVersion >= gestalt32BitQD))
- {
- if (bytesPerRow <= kMaxRowBytes)
- {
- if (depth <= 8)
- if (colors == NULL)
- err = paramErr;
- }
- else
- err = paramErr;
- }
- else
- err = paramErr;
- }
-
- if (err == noErr)
- {
- tempCGrafPort = (CGrafPtr)NewPtr(sizeof (CGrafPort) );
- if (tempCGrafPort != NULL)
- {
- GetPort( &savedPort );
- OpenCPort( tempCGrafPort );
- tempCGrafPort->portRect = *bounds;
- RectRgn( tempCGrafPort->visRgn, bounds );
- ClipRect( bounds );
-
- err = SetUpPixMap(tempCGrafPort->portPixMap, depth, bounds, colors, bytesPerRow);
-
- if (err == noErr)
- {
- EraseRect(bounds);
-
- newPixMap = tempCGrafPort->portPixMap;
- }
- SetPort(savedPort);
- }
- else
- err = MemError();
- }
-
- if (colors != NULL)
- HSetState((Handle)colors, savedState);
-
- if (err != noErr)
- {
- if (newPixMap != NULL)
- {
- DisposeCTable((**newPixMap).pmTable);
- DisposePtr((**newPixMap).baseAddr);
- }
-
- if (tempCGrafPort != NULL)
- {
- CloseCPort(tempCGrafPort);
- DisposePtr((Ptr)tempCGrafPort);
- }
- }
- else
- {
- *newCGrafPort = tempCGrafPort;
- }
-
- return err;
- }
-
-
-
-
- #define kDefaultRes 0x00480000
-
- static OSErr SetUpPixMap(
- PixMapHandle aPixMap,
- short depth,
- Rect *bounds,
- CTabHandle colors,
- short bytesPerRow)
- {
- CTabHandle newColors;
- Ptr offBaseAddr;
- OSErr err;
-
- err = noErr;
- newColors = NULL;
- offBaseAddr = NULL;
-
- if (depth <= 8)
- {
- newColors = colors;
- err = HandToHand( (Handle *)&newColors );
- }
- else
- {
- newColors = (CTabHandle)NewHandle(sizeof(ColorTable) - sizeof(CSpecArray));
- err = MemError();
- }
-
- if (err == noErr)
- {
- offBaseAddr = NewPtr((Size)bytesPerRow *
- (bounds->bottom - bounds->top) );
- if (offBaseAddr != NULL)
- {
- (**aPixMap).baseAddr = offBaseAddr;
- (**aPixMap).rowBytes = bytesPerRow | 0x8000;
- (**aPixMap).bounds = *bounds;
- (**aPixMap).pmVersion = 0;
- (**aPixMap).packType = 0;
- (**aPixMap).packSize = 0;
- (**aPixMap).hRes = kDefaultRes;
- (**aPixMap).vRes = kDefaultRes;
- (**aPixMap).pixelSize = depth;
- (**aPixMap).planeBytes = 0;
- (**aPixMap).pmReserved = 0;
-
- if (depth <= 8)
- {
- (**aPixMap).pixelType = 0;
- (**aPixMap).cmpCount = 1;
- (**aPixMap).cmpSize = depth;
- (**aPixMap).pmTable = newColors;
- }
- else
- {
- (**aPixMap).pixelType = RGBDirect;
- (**aPixMap).cmpCount = 3;
- if (depth == 16)
- (**aPixMap).cmpSize = 5;
- else
- (**aPixMap).cmpSize = 8;
- (**newColors).ctSeed = 3 * (**aPixMap).cmpSize;
- (**newColors).ctFlags = 0;
- (**newColors).ctSize = 0;
- (**aPixMap).pmTable = newColors;
- }
- }
- else
- err = MemError();
- }
- else
- newColors = NULL;
-
- if (err != noErr)
- {
- if (newColors != NULL)
- DisposeCTable( newColors );
- }
-
- return err;
- }
-